package com.endbd.gateway.globalfilter;

import com.endbd.feignapi.api.SystemApi;
import com.endbd.feignapi.model.system.Job;
import com.endbd.feignapi.model.system.User;
import com.endbd.feignapi.util.LoginToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.NettyWriteResponseFilter;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class loginCheck implements GlobalFilter, Ordered {

    @Autowired
    private RedisTemplate redisTemplate;


    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String uri = exchange.getRequest().getURI().toString();
        //判断是否为登录或登出请求
        if (uri.contains("/system/permission/login")
                || uri.contains("/system/permission/logout")
                || uri.contains("/system/permission/uIdCheck")) {
            //直接放行
            return chain.filter(exchange);
        }

        HttpHeaders headers = exchange.getRequest().getHeaders();
        List<String> uIdList = headers.get("uId");
        List<String> tokenList = headers.get("token");
        String uId;
        String strToken;

        //判断登录状态
        if (uIdList == null || tokenList == null) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);//未登录
            return exchange.getResponse().setComplete();
        } else {
            uId = uIdList.get(0);
            strToken = tokenList.get(0);
            if (uId == null || strToken == null) {
                exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);//未登录
                return exchange.getResponse().setComplete();
            }
        }

        /*
        1.0版
         */
//        Map<String, User> loginUserMap = (Map<String, User>) redisTemplate.opsForValue().get("loginUser");
//        if (loginUserMap == null) loginUserMap = new HashMap<>();
//        User user = loginUserMap.get(uId);
//        if (user == null) {
//            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);//未登录
//            return exchange.getResponse().setComplete();
//        } else { //判断登录是否过期
//            Map<String, Date> loginTimeMap = (Map<String, Date>) redisTemplate.opsForValue().get("loginTime");
//            if (loginTimeMap == null) loginTimeMap = new HashMap<>();
//            Date loginTime = loginTimeMap.get(uId);
//            if (loginTime == null) {
//                exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);//登录失效
//                return exchange.getResponse().setComplete();
//            }
//            long time = loginTime.getTime();
//            if (new Date().getTime() - time > 1000 * 60 * 30) {
//                loginUserMap.remove(uId);
//                loginTimeMap.remove(uId);
//                redisTemplate.opsForValue().set("loginUser", loginUserMap);
//                redisTemplate.opsForValue().set("loginTime", loginTimeMap);
//                exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);//登录失效
//                return exchange.getResponse().setComplete();
//            }
//        }

        /*
        2.0版
         */
        Map<String, LoginToken> loginToken = (Map<String, LoginToken>) redisTemplate.opsForValue().get("loginToken");
        if (loginToken == null) loginToken = new HashMap<>();

        LoginToken token = loginToken.get(uId);
        if (token == null || !strToken.equals(token.getToken())) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);//未登录
            return exchange.getResponse().setComplete();
        } else { //判断登录是否过期
            Date loginTime = token.getLoginTime();
            if (loginTime == null || new Date().getTime() - loginTime.getTime() > 1000 * 60 * 30) {
                exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);//登录失效
                return exchange.getResponse().setComplete();
            } else {
                token.setLoginTime(new Date());
            }
        }

        //读取job添加进请求头
        String jobId = String.valueOf(token.getJob());
        ServerHttpRequest request = exchange.getRequest().mutate().header("jobId", jobId).build();

        return chain.filter(exchange.mutate().request(request).build());
//        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER - 10;
    }
}
